﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Web.Script.Serialization;
using ReservaWCF.Dominio;
using ReservaWCF.Persistencia;
using System.Data.SqlClient;
using System.Messaging;

namespace ReservaWCF
{

    public class RVReserva : IRVReserva
    {
        public Reserva GrabarReserva(Reserva reserva)
        {
            int reservaID = 0;
            bool resultado;
            string mensaje = string.Empty;
            ReservaDAO ReservaDAO = new ReservaDAO();

            //Validacion de Lista de Pasajeros
            if (reserva.DetalleReservaPasajero == null || reserva.DetalleReservaPasajero.Count == 0)
                throw new FaultException<ValidationException>(new ValidationException { ValidationError = "No hay pasajeros para realizar reserva" }, new FaultReason("Lista de Pasajeros Vacia"));

            //Validacion de Datos de pago
            if (reserva.PagoReserva == null)
                throw new FaultException<ValidationException>(new ValidationException { ValidationError = "Verificar los datos de la tarjeta" }, new FaultReason("Datos de Pago errados"));


            //1. Recibir Objeto Reserva y Grabar
            TB_RESERVA_VUELO ReservaVuelo = new TB_RESERVA_VUELO();
            
            ReservaVuelo.RESERVA_FECHA = reserva.FechaReserva;
            ReservaVuelo.RESERVA_ESTADO = reserva.Estado;
            ReservaVuelo.RESERVA_COMENTARIOS = reserva.Comentario;
            ReservaVuelo.FEC_SALIDA = reserva.FechaSalida;
            ReservaVuelo.FEC_REGRESO = reserva.FechaRegreso;
            ReservaVuelo.FEC_REGRESO = reserva.FechaRegreso;
            ReservaVuelo.CIU_ID_ORIGEN = reserva.CiudadOrigen;
            ReservaVuelo.CIU_ID_DESTINO = reserva.CiudadDestino;
            ReservaVuelo.VUELO_TIPO = reserva.TipoVuelo;
            ReservaVuelo.VUELO_MONTO_PAGO = reserva.MontoPago;
            ReservaVuelo.CONTACTO_NOM = reserva.NombreContacto;
            ReservaVuelo.CONTACTO_APE = reserva.ApellidoContacto;
            ReservaVuelo.CONTACTO_DIREC = reserva.DireccionContacto;
            ReservaVuelo.CONTACTO_EMAIL = reserva.EmailContacto;
            ReservaVuelo.CONTACTO_TELF = reserva.TelefonoContacto;

            //1. Instanciar el objeto
            ServicioVueloWS.ProveedorVuelosServiceClient proxy = new ServicioVueloWS.ProveedorVuelosServiceClient();

            //2. Invocar al metodo 

            ReservaVuelo.RESERVA_CODIGO = proxy.GenerarReserva();

            reservaID = ReservaDAO.GrabarReserva(ReservaVuelo, ref mensaje);

            //PAGO DE RESERVA  http://localhost:50541/Tarjetas.svc/Pagos 
            //reserva.PagoReserva

            PagoReserva pagoCreado = new PagoReserva();

            //Prueba de creacion de pago via HTTP POST
            if (reserva.PagoReserva != null)
            {
                try
                {

                    JavaScriptSerializer js = new JavaScriptSerializer();
                    string postdata = js.Serialize(reserva.PagoReserva);

                    //string postdata = "{\"NumeroTarjeta\":\"" + reserva.PagoReserva.NumeroTarjeta + "\",\"MesExpira\":\"" 
                    //                + reserva.PagoReserva.MesExpira.ToString() + "\",\"AnioExpira\":\"" + reserva.PagoReserva.AnioExpira.ToString()
                    //                + "\",\"CVV\":\"" + reserva.PagoReserva.CVV.ToString() + "\",\"CVV\":\"" + reserva.PagoReserva.MontoReserva.ToString() + "\"}"; //JSON
                    byte[] data = Encoding.UTF8.GetBytes(postdata);
                    HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://localhost:50541/Tarjetas.svc/Pagos");
                    req.Method = "POST";
                    req.ContentLength = data.Length;
                    req.ContentType = "application/json";
                    var reqStream = req.GetRequestStream();
                    reqStream.Write(data, 0, data.Length);
                    var res = (HttpWebResponse)req.GetResponse();
                    StreamReader reader = new StreamReader(res.GetResponseStream());
                    string pagoJson = reader.ReadToEnd();

                    pagoCreado = js.Deserialize<PagoReserva>(pagoJson);
                }
                catch (WebException e)
                {
                    HttpStatusCode code = ((HttpWebResponse)e.Response).StatusCode;
                    string message = ((HttpWebResponse)e.Response).StatusDescription;
                    StreamReader reader = new StreamReader(e.Response.GetResponseStream());
                    string error = reader.ReadToEnd();
                    JavaScriptSerializer js1 = new JavaScriptSerializer();
                    string mensajeError = js1.Deserialize<string>(error);
                    throw new FaultException<ValidationException>(new ValidationException { ValidationError = mensajeError }, new FaultReason("Datos de Pago errados"));
                    
                }

            }
            //TRANSACCION RESERVA
            //1. Instanciar el objeto
            TransaccionWS.RVTransaccionClient proxyTransaccion = new TransaccionWS.RVTransaccionClient();

            //2. Invocar al metodo 
            TransaccionWS.PagoReserva pagoTransaccion = new TransaccionWS.PagoReserva();

            if (pagoCreado != null)
            {
                pagoTransaccion.ReservaID = reservaID;
                pagoTransaccion.NumeroTxn = pagoCreado.NumeroTxn;
            }

            int pagoID = proxyTransaccion.GrabarPago(pagoTransaccion);

            string codigoPago = string.Format("{0:000000}", pagoID);

            //2.- Grabar Detalles solo si resevaID es mayor a 0
            if (reservaID > 0)
            { 
            
                //2.1.- Detalle Reserva Pasajero
                if (reserva.DetalleReservaPasajero != null && reserva.DetalleReservaPasajero.Count > 0)
                {
                    foreach (DetalleReservaPasajero detalle in reserva.DetalleReservaPasajero)
                    {
                        TB_RESERVA_PAX detalleReservaPasajero = new TB_RESERVA_PAX();

                        detalleReservaPasajero.PAX_ID = ReservaDAO.ObtenerCorrelativoDetallePasajero(reservaID);
                        detalleReservaPasajero.RESERVA_ID = reservaID;
                        detalleReservaPasajero.PAX_NOM = detalle.NombrePAX;
                        detalleReservaPasajero.PAX_APE_PAT = detalle.ApellidoPaternoPAX;
                        detalleReservaPasajero.PAX_FEC_NAC = detalle.FechaNacimientoPAX;
                        detalleReservaPasajero.PAX_TIPO = detalle.TipoPAX;
                        detalleReservaPasajero.PAX_TIPO_DOC = detalle.TipoDocumentoPAX;
                        detalleReservaPasajero.PAX_NUM_DOC = detalle.NumeroDocumentoPAX;
                        detalleReservaPasajero.PAX_PAIS_ID = detalle.PaisIDPAX;
                        detalleReservaPasajero.ASIENTO = detalle.Asiento;
                        detalleReservaPasajero.TARIFA = detalle.Tarifa;
                        detalleReservaPasajero.IMPUESTOS = detalle.Impuesto;
                        detalleReservaPasajero.FEE = detalle.FEE;

                        resultado = ReservaDAO.GrabarDetallePasajero(detalleReservaPasajero, ref mensaje);
                    
                    }
                }

                
                //2.2.- Detalle Reserva Segmento
                if (reserva.DetalleReservaSegmento != null && reserva.DetalleReservaSegmento.Count > 0)
                {
                    foreach (DetalleReservaSegmento detalle in reserva.DetalleReservaSegmento)
                    {
                        TB_RESERVA_SEGMENTO detalleReservaSegmento = new TB_RESERVA_SEGMENTO();

                        detalleReservaSegmento.SEGMENTO_ID = ReservaDAO.ObtenerCorrelativoDetalleSegmento(reservaID);
                        detalleReservaSegmento.RESERVA_ID = reservaID;
                        detalleReservaSegmento.VUELO_NRO = detalle.NumeroVuelo;
                        detalleReservaSegmento.LA_ID = detalle.LAID;
                        detalleReservaSegmento.FEC_SALIDA = detalle.FechaSalida;
                        detalleReservaSegmento.FEC_LLEGADA = detalle.FechaLlegada;
                        detalleReservaSegmento.CIU_ID_ORIGEN = detalle.CiudadOrigenID;
                        detalleReservaSegmento.CIU_ID_DESTINO = detalle.CiudadDestinoID;
                        detalleReservaSegmento.ES_RETORNO = detalle.EsRetorno;
                        
                        resultado = ReservaDAO.GrabarDetalleSegmento(detalleReservaSegmento, ref mensaje);

                    }
                }
            
            }

            //reserva mensaje
            reserva.ReservaID = reservaID;
            reserva.MensajeNoOK = mensaje;
            reserva.CodigoReserva = ReservaVuelo.RESERVA_CODIGO;
            reserva.CodigoPago = codigoPago;


            //ENVIAR DATOS A LA COLA
            string asunto = "Confirmacion de Reserva";
            string correoDestino = ReservaVuelo.CONTACTO_EMAIL;
            string mensajeBody = "Estimado Cliente: \n \n Se ha generado la reserva " + ReservaVuelo.RESERVA_CODIGO + "\n y se ha efectuado la transacción de pago Nro." + codigoPago + " satisfactoriamente.";

            // 1. Enviamos la nota original vía la cola de entrada del servidor (In)
            string rutaColaIn = @".\private$\persuation";
            if (!MessageQueue.Exists(rutaColaIn))
                MessageQueue.Create(rutaColaIn);
            MessageQueue colaIn = new MessageQueue(rutaColaIn);
            Message mensajeIn = new Message();
            mensajeIn.Label = "Nueva Notificacion";
            mensajeIn.Body = new Notificacion() { Asunto = asunto, CorreoDestino = correoDestino, MensajeBody = mensajeBody };
            colaIn.Send(mensajeIn);

            
            ReservaDAO = null;

            return reserva;

        }
        
        public void EmitirReserva(int pIntIdReserva)
        {
            Persistencia.ReservaDAO objReservaDAO = new Persistencia.ReservaDAO();
             objReservaDAO.EmitirReserva(pIntIdReserva);
        } 

        public List<Reserva> ListarReserva(DateTime pDatFecIni, DateTime pDatFecFin, String pStrEstado, String pStrCodigo)
                    {
            Persistencia.ReservaDAO objReservaDAO = new Persistencia.ReservaDAO();
            return objReservaDAO.ListarPorFiltro(pDatFecIni, pDatFecFin, pStrEstado, pStrCodigo);
        }

        public Reserva BuscarReserva(int pIntIdReserva)
        {
            Persistencia.ReservaDAO objReservaDAO = new Persistencia.ReservaDAO();
            return objReservaDAO.ObtenerReserva(pIntIdReserva);
            }
    }
}
